package com.unito.tableplus.server.services;

import java.util.HashMap;
import java.util.ArrayList;
//import java.util.List;
import java.util.Map;

import javax.jdo.PersistenceManager;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.unito.tableplus.client.services.TableService;
import com.unito.tableplus.server.persistence.TableQueries;
import com.unito.tableplus.server.persistence.UserQueries;
import com.unito.tableplus.server.persistence.WalletQueries;
import com.unito.tableplus.server.util.ServiceFactory;
import com.unito.tableplus.shared.model.BlackBoardMessage;
//import com.unito.tableplus.shared.model.Bookmark;
import com.unito.tableplus.shared.model.Provider;
import com.unito.tableplus.shared.model.Resource;
import com.unito.tableplus.shared.model.TableObject;
import com.unito.tableplus.shared.model.Table;
import com.unito.tableplus.shared.model.User;
import com.unito.tableplus.shared.model.UserStatus;
import com.unito.tableplus.shared.model.Wallet;

public class TableServiceImpl extends RemoteServiceServlet implements TableService {

	private static final long serialVersionUID = -3403034728905706407L;
	
	@Override
	public Table storeNewTable(Table table, User creator){
		return TableQueries.storeNewTable(table, creator);
	}

	@Override
	public Map<Long,Table> queryTables(ArrayList<Long> keys) {
		Map<Long,Table> tablesMap = null;
		ArrayList<Table> tablesList = TableQueries.queryTables(keys);
		//List<Table> tablesList = TableQueries.queryTables(keys);
		if(tablesList != null){
			tablesMap = new HashMap<Long,Table>();
			for(Table t : tablesList)
				tablesMap.put(t.getKey(), t);
			}
		return tablesMap;
	}

	@Override
	public boolean storeTable(Table table) {
		return TableQueries.storeTable(table);
	}

	@Override
	public Table queryTable(Long key) {
		return TableQueries.queryTable(key);
	}

	@Override
	public void deleteTable(Long key) {
		TableQueries.deleteTable(key);
	}
	
	@Override
	public Map<Long,UserStatus> queryUsersStatus(Long tableKey){
		return TableQueries.queryMembersStatus(tableKey);
	}
	
	@Override
	public String setUserStatus(Long tableKey, Long userKey, UserStatus status){
		return TableQueries.setUserStatus(tableKey,userKey,status);
	}

	@Override
	public boolean addBlackBoardMessage(Long key, BlackBoardMessage bbMessage) {
		return TableQueries.addMessage(key, bbMessage);
	}

	@Override
	public void removeMessage(String messageKey) {
		TableQueries.removeMessage(messageKey);
	}

	@Override
	public boolean clearMessages(Long key) {
		return TableQueries.clearMessages(key);
	}

	@Override
	public ArrayList<TableObject> loadTableObjects(Long tableKey) {
			return TableQueries.queryObjects(tableKey);
	}
	
	@Override
	public boolean addObject(Resource resource, User user, Long tableKey) {
		Provider resourceProvider = resource.getProvider();
		//TODO check if object has already been added
		if(resourceProvider.equals(Provider.DRIVE)){
			Wallet wallet = WalletQueries.getWallet(user.getKey());
			//arrayList invece di list
			ArrayList<Long> userKeys = TableQueries.queryTable(tableKey).getMembers();
			ArrayList<User> users = UserQueries.queryUsers(userKeys);
			ArrayList<String> userEmails = new ArrayList<String>();
			for(User u : users)
				userEmails.add(u.getEmail());
			userEmails.remove(user.getEmail());//owner removed from list
			if(!userEmails.isEmpty())
			DriveServiceImpl.shareFile(resource.getKey(), wallet, userEmails);
			//DriveServiceImpl.shareFile(resource.getId(), wallet, userEmails); MAGIO
			
		} else if(resourceProvider.equals(Provider.DROPBOX)){
			Wallet wallet = WalletQueries.getWallet(user.getKey());
			String shareLink = DropBoxServiceImpl.shareFile(wallet, resource.getKey());
			//String shareLink = DropBoxServiceImpl.shareFile(wallet, resource.getId()); MAGIO
			resource.setURI(shareLink);
		}
			
		return TableQueries.addResource(resource, tableKey);
	}

	@Override
	public void addMember(Long currentUserKey, Long newUserKey, Long tableKey) {
		User user = UserQueries.queryUser(newUserKey);
		Wallet wallet = WalletQueries.getWallet(currentUserKey);
		TableQueries.addMember(newUserKey, tableKey);
		//List<TableObject> resources = TableQueries.queryObjects(tableKey);
		ArrayList<TableObject> resources = TableQueries.queryObjects(tableKey);
		if(wallet.getDriveAccessToken() != null)
		for(Resource r : resources){
			ArrayList<String> toShare = new ArrayList<String>();
			//List<String> toShare = new ArrayList<String>();
			if(r.getProvider().equals(Provider.DRIVE))
				toShare.add(r.getKey());
			//toShare.add(r.getId()); MAGIO
			if(!toShare.isEmpty())
			DriveServiceImpl.shareFiles(toShare, wallet, user.getEmail());
		}
	}

	@Override
	public ArrayList<BlackBoardMessage> loadBlackBoardMessages(Long tableKey) {
		return TableQueries.queryMessages(tableKey);
	}

	@Override
	public TableObject queryObject(String key) {
		PersistenceManager pm = ServiceFactory.getPmfInstance().getPersistenceManager();
		TableObject o = null;
		try {
			Object object = pm.getObjectById(TableObject.class, key);
			//Object object = pm.getObjectById(Bookmark.class, key);
			o = (TableObject) pm.detachCopy(object);
		} catch (Exception e) {
			System.err.println("There has been an error querying object: " + e);
		} finally {
			pm.close();
		}
		return o;
	}

	public String editComment(TableObject b, String key) {
		return TableQueries.editComment(b, key);
		
	}

}
